一对一


1. 什么时候一对一?

  • 当一张表的某一些字段查询的比较频繁,另外一些字段查询的不是特别频繁,把不怎么常用的字段 单独拿出来做成一张表 然后用过一对一关联起来

2. 一对一的好处

  • 既保证数据都完整的保存下来,又能保证大部分的检索速度更快

3. 使用 OneToOneField 创建一对一设计模式

  • models.OneToOneField(to='表的类名', to_field='字段名', on_delete=models.CASCADE)

  • ForeignKey 的参数解释:

    • to -> 设置需要关联表的类名
      • to='Classes' -> 加上引号是为了在当前models.py文件中通过反射去查询表的类
      • to=Classes -> 不加引号,直接使用表的类,如果Classes类定义在to的表类下面那么就会报错,因为Classes未定义就引用了
    -> 不加引号的使用场景: 使用导入的表类时无需加引号(不会出现上面的报错情况,因为表类在文件一开始就已经导入了)
    • to_field -> 设置关联表的那个字段,如果不传默认关联 id
    • on_delete -> 和 ForeignKey 中的一样

# 学生表
class Student(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=10)
    age = models.IntegerField()
    detail = models.OneToOneField(to='StudentDetail')


# 学生详情表
class StudentDetail(models.Model):
    hobby = models.CharField(max_length=10)
    address = models.CharField(max_length=10)

OnetoOneField字段相关


  • OneToOneField字段相关的和外键字段相关的是一样的(不懂的看回外键章节中的外键字段相关的)

查询相关


1.正向查询

  • 正向查询用字段,反向查询用表名

  • OneToOneField 和 ForeignKey 的正向查询是一样的,这里就不列举了,不懂看回上面 ForeignKey 的正向查询

student_detail_obj = Student.objects.get(id=1).detail  # StudentDetail object -> 返回值: 与查询到的 student 数据相关的 detail 数据的对象

student_detail_hobby = Student.objects.get(id=1).detail.hobby  # 篮球

2. 反向查询

  • 正向查询用字段,反向查询用表名

  • 注意: OneToOneField 和 ForeignKey 的反向查询有点不一样,OneToOneField 直接主表的类名无需加 _set,且主表类名首字母无需大写

  • 语法: 查询到的对象.主表的类名 -> 主表类名首字母无需大写

student_obj = StudentDetail.objects.get(id=1).student  # Student object -> 返回值: 反向查询到的 StudentDetail 数据相关的 student 数据的对象

student_name = StudentDetail.objects.get(id=1).student.name  # Kevin